home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 June / macformat-038.iso / Shareware in MacFormat / Creator Changer 2.5 / Code & Resource / GetFileIcon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-12  |  7.6 KB  |  357 lines  |  [TEXT/KAHL]

  1. #include "GetFileIcon.h"
  2. #include "Folders.h"
  3.  
  4.  
  5. pascal OSErr GetFileIcon(FSSpec *thing, IconSelectorValue iconSelector, Handle *theSuite)
  6.     {
  7.     
  8.     CInfoPBRec        cpb;
  9.     OSErr            err;
  10.  
  11.     *theSuite = NULL;
  12.  
  13.     if(IsVolEjected(thing->vRefNum)) err=volOffLinErr;
  14.     else
  15.         {
  16.         cpb.hFileInfo.ioVRefNum=thing->vRefNum;
  17.         cpb.hFileInfo.ioDirID=thing->parID;
  18.         cpb.hFileInfo.ioNamePtr=thing->name;
  19.         cpb.hFileInfo.ioFDirIndex=0;
  20.         err=PBGetCatInfoSync(&cpb);
  21.  
  22.         if(!err)
  23.             if((cpb.hFileInfo.ioFlAttrib & ioDirMask)==0) err=GetNormalFileIcon(&cpb, iconSelector, theSuite);
  24.         }
  25.     return(err);
  26.     }
  27.  
  28.  
  29.  
  30. static Boolean IsVolEjected(short vRefNum)
  31.     {
  32.     
  33.     OSErr            err;
  34.     HVolumeParam    vol_pb;
  35.     
  36.     vol_pb.ioNamePtr=NULL;
  37.     vol_pb.ioVRefNum=vRefNum;
  38.     vol_pb.ioVolIndex=0;
  39.     err=PBHGetVInfoSync((HParmBlkPtr)&vol_pb);
  40.     
  41.     return((err==noErr)&&(vol_pb.ioVDRefNum>0));
  42.     }
  43.  
  44.  
  45.  
  46. static OSErr GetNormalFileIcon(CInfoPBRec *cpb, IconSelectorValue iconSelector, Handle *theSuite)
  47.     {
  48.     OSErr            err;
  49.     long            dataSize;
  50.     Handle            iconData;
  51.     Byte            iconType;
  52.     GetIconData        getData;
  53.     short            iconID;
  54.     Boolean        inFinder;
  55.     short            saveResFile, FinderResFile, sysVRefNum;
  56.     long            sysDirID;
  57.     Str255            finderName;
  58.     IconActionUPP    getIconProcPtr;
  59.  
  60.     iconID=FindGenericIconID(cpb->hFileInfo.ioFlFndrInfo.fdType, &inFinder );
  61.     saveResFile=CurResFile();
  62.  
  63.     if(inFinder)
  64.         {
  65.         FindFolder(kOnSystemDisk, kSystemFolderType, kDontCreateFolder, &sysVRefNum, &sysDirID);
  66.         SetResLoad(false);
  67.         GetFinderFilename(finderName);
  68.         FinderResFile=HOpenResFile(sysVRefNum, sysDirID, finderName, fsRdPerm);
  69.         SetResLoad(true);
  70.         if(FinderResFile==-1) err=ResError();
  71.          else
  72.             {
  73.             err=GetResourceIcons(theSuite, iconID, iconSelector);
  74.             CloseResFile(FinderResFile);
  75.             }
  76.         }
  77.     else
  78.         {
  79.         getData.DTRefNum=FindDesktopDatabase(cpb->dirInfo.ioVRefNum, cpb->hFileInfo.ioFlFndrInfo.fdCreator);
  80.         if(getData.DTRefNum!=0)
  81.             {
  82.             err=NewIconSuite(theSuite);
  83.             if(!err)
  84.                 {
  85.                 getData.fileCreator    = cpb->hFileInfo.ioFlFndrInfo.fdCreator;
  86.                 getData.fileType    = cpb->hFileInfo.ioFlFndrInfo.fdType;
  87.                 if(getData.fileType == kApplicationAliasType) getData.fileType='APPL';
  88.                  getIconProcPtr=NewIconActionProc(GetIconProc);
  89.                 err=ForEachIconDo(*theSuite, iconSelector, getIconProcPtr, &getData);
  90.                 DisposeRoutineDescriptor(getIconProcPtr);
  91.                 }
  92.             }
  93.         if((getData.DTRefNum==0) || IsSuiteEmpty(*theSuite))
  94.             {
  95.             UseResFile(0);
  96.             err=GetResourceIcons(theSuite, iconID, iconSelector);
  97.             }
  98.         }
  99.     UseResFile(saveResFile);
  100.  
  101.     return(err);
  102.     }
  103.  
  104.  
  105.  
  106. static void GetFinderFilename(StringPtr _finderFilename)
  107.     {
  108.     
  109.     Str255        _defaultFinderFilename="\pFinder";
  110.     StringPtr    _lowMemFinderName;
  111.  
  112.     _lowMemFinderName = LMGetFinderName();
  113.     if((_lowMemFinderName!=(StringPtr)nil)&&(_lowMemFinderName[0]>0)) BlockMove(_lowMemFinderName, _finderFilename, _lowMemFinderName[0]+1);
  114.     else BlockMove(_defaultFinderFilename, _finderFilename, _defaultFinderFilename[0]+1);
  115.     }
  116.  
  117.  
  118.  
  119. static pascal OSErr GetIconProc(ResType theType, Handle *theIcon, void *yourDataPtr)
  120.     {
  121.     
  122.     OSErr            err;
  123.     GetIconData        *data;
  124.     DTPBRec            deskRec;
  125.  
  126.     err=noErr;
  127.     data=(GetIconData *)yourDataPtr;
  128.     *theIcon=NewHandle(kLarge8BitIconSize);
  129.  
  130.     if(!(*theIcon)) err=memFullErr;
  131.     else
  132.         {
  133.         HLock(*theIcon);
  134.     
  135.         deskRec.ioDTRefNum        = data->DTRefNum;
  136.         deskRec.ioDTBuffer        = **theIcon;
  137.         deskRec.ioDTReqCount    = kLarge8BitIconSize;
  138.         deskRec.ioFileCreator    = data->fileCreator;
  139.         deskRec.ioFileType        = data->fileType;
  140.     
  141.         switch(theType)
  142.             {
  143.             case large1BitMask:
  144.                 deskRec.ioIconType = kLargeIcon;
  145.                 break;
  146.             case large4BitData:
  147.                 deskRec.ioIconType = kLarge4BitIcon;
  148.                 break;
  149.             case large8BitData:
  150.                 deskRec.ioIconType = kLarge8BitIcon;
  151.                 break;
  152.             case small1BitMask:
  153.                 deskRec.ioIconType = kSmallIcon;
  154.                 break;
  155.             case small4BitData:
  156.                 deskRec.ioIconType = kSmall4BitIcon;
  157.                 break;
  158.             case small8BitData:
  159.                 deskRec.ioIconType = kSmall8BitIcon;
  160.                 break;
  161.             default:
  162.                 deskRec.ioIconType = 1000;
  163.                 break;
  164.             }
  165.  
  166.         err=PBDTGetIconSync(&deskRec);
  167.         if(err==noErr)
  168.             {
  169.             HUnlock(*theIcon);
  170.             SetHandleSize(*theIcon, deskRec.ioDTActCount);
  171.             }
  172.         else
  173.             {
  174.             DisposeHandle(*theIcon);
  175.             *theIcon=NULL;
  176.             err=noErr;
  177.             }
  178.         }
  179.     return(err);
  180.     }
  181.  
  182.  
  183.  
  184. static short FindDesktopDatabase(short firstVRefNum, OSType fileCreator)
  185.     {
  186.     
  187.     OSErr            err;
  188.     VolumeParam        vpb;
  189.     short            DTRefNum = 0;
  190.  
  191.     if(!InOneDesktop(firstVRefNum, fileCreator, &DTRefNum))
  192.         {
  193.         vpb.ioNamePtr=NULL;
  194.         for(vpb.ioVolIndex=1; PBGetVInfoSync((ParmBlkPtr)&vpb)==noErr; ++vpb.ioVolIndex)
  195.             {
  196.             if(vpb.ioVRefNum == firstVRefNum) continue;
  197.             if( InOneDesktop(vpb.ioVRefNum, fileCreator, &DTRefNum)) break;
  198.             }
  199.         }
  200.     return(DTRefNum);
  201.     }
  202.  
  203.  
  204.  
  205. static Boolean InOneDesktop(short vRefNum, OSType fileCreator, short *dtRefNum)
  206.     {
  207.     
  208.     OSErr        err;
  209.     DTPBRec        deskRec;
  210.     Boolean        retVal;
  211.     
  212.     HParamBlockRec         _myHPB;
  213.     GetVolParmsInfoBuffer  _infoBuffer;
  214.     
  215.     retVal=false;
  216.     deskRec.ioNamePtr=NULL;
  217.     deskRec.ioVRefNum=vRefNum;
  218.     
  219.     _myHPB.ioParam.ioNamePtr  = (StringPtr)nil;
  220.     _myHPB.ioParam.ioVRefNum  = vRefNum;
  221.     _myHPB.ioParam.ioBuffer   = (Ptr)&_infoBuffer;
  222.     _myHPB.ioParam.ioReqCount = sizeof(_infoBuffer);
  223.     if(((err=PBHGetVolParms(&_myHPB,false))!=noErr) || ((_infoBuffer.vMAttrib&(1L<<bHasDesktopMgr))==0)) return(retVal);
  224.     err=PBDTGetPath(&deskRec);
  225.     if(!err)
  226.         {
  227.         deskRec.ioFileCreator=fileCreator;
  228.         deskRec.ioIndex=1;
  229.         do
  230.             {
  231.             deskRec.ioTagInfo=0;
  232.             err=PBDTGetIconInfoSync(&deskRec);
  233.             deskRec.ioIndex+=1;
  234.             } while((err == noErr)&&(deskRec.ioIconType<=0));
  235.     
  236.         if(err==noErr)
  237.             {
  238.             retVal=true;
  239.             *dtRefNum=deskRec.ioDTRefNum;
  240.             }
  241.         }
  242.     return(retVal);
  243.     }
  244.  
  245.  
  246.  
  247. static pascal OSErr GetResourceIcons(Handle *theSuite, short theID, long theSelector)
  248.     {
  249.     
  250.     OSErr    err;
  251.     
  252.     err=Get1IconSuite(theSuite, theID, theSelector);
  253.     if(err == noErr) err=CopyEachIcon(*theSuite);
  254.     return(err);
  255.     }
  256.  
  257.  
  258.  
  259. static pascal OSErr CopyOneIcon(ResType theType, Handle *theIcon, void *yourDataPtr)
  260.     {
  261.     
  262.     OSErr    err;
  263.     
  264.     if(*theIcon!=NULL)
  265.         {
  266.         LoadResource(*theIcon);
  267.         err=HandToHand(theIcon);
  268.         if(err!=noErr) *theIcon=NULL;
  269.         }
  270.     return(noErr);
  271.     }
  272.  
  273.  
  274.  
  275. static OSErr CopyEachIcon(Handle theSuite)
  276.     {
  277.     IconActionUPP    copyOneIconProc;
  278.     OSErr            err;
  279.     
  280.     copyOneIconProc=NewIconActionProc(CopyOneIcon);
  281.     err=ForEachIconDo(theSuite, svAllAvailableData, copyOneIconProc, NULL);
  282.     DisposeRoutineDescriptor(copyOneIconProc);
  283.     return(err);
  284.     }
  285.  
  286.  
  287.  
  288. static short FindGenericIconID(OSType theType, Boolean *inFinder)
  289.     {
  290.     
  291.     short                 id=genericDocumentIconResource;
  292.     GenericIconInfo        *_icon, *_endIcon;
  293.    
  294.     for(_icon=gGenericFinderIcons, _endIcon=_icon+sizeof(gGenericFinderIcons)/sizeof(GenericIconInfo);(_icon<_endIcon)&&(_icon->type!=theType);_icon++);
  295.     if(!(*inFinder=(_icon<_endIcon)))
  296.         for(_icon=gGenericSysIcons, _endIcon=_icon+sizeof(gGenericSysIcons)/sizeof(GenericIconInfo);(_icon<_endIcon)&&(_icon->type!=theType); _icon++);
  297.     if(_icon<_endIcon) id=_icon->id;
  298.     return(id);
  299.     }
  300.  
  301.  
  302.  
  303. static pascal OSErr Get1IconSuite(Handle *theSuite, short theID, long theSelector)
  304.     {
  305.     
  306.     OSErr            err;
  307.     IconActionUPP    get1IconProc;
  308.  
  309.     err=NewIconSuite(theSuite);
  310.     if(!err)
  311.         {
  312.         get1IconProc=NewIconActionProc(Get1Icon);
  313.         err=ForEachIconDo(*theSuite, theSelector, get1IconProc, &theID);
  314.         DisposeRoutineDescriptor(get1IconProc);
  315.         }
  316.     return(err);
  317.     }
  318.  
  319.  
  320.  
  321. static pascal OSErr Get1Icon(ResType theType, Handle *theIcon, short *resID)
  322.     {
  323.     
  324.     *theIcon = Get1Resource(theType, *resID);
  325.  
  326.     return( noErr );
  327.     }
  328.  
  329.  
  330.  
  331. static pascal OSErr TestHandle(ResType theType, Handle *theIcon, void *yourDataPtr)
  332.     {
  333.     
  334.     if(*theIcon!=NULL) *(Boolean *)yourDataPtr=false;
  335.  
  336.     return( noErr );
  337.     }
  338.  
  339.  
  340.  
  341. Boolean IsSuiteEmpty(Handle theSuite)
  342.     {
  343.     
  344.     Boolean            retVal;
  345.     IconActionUPP    testHandleProc;
  346.  
  347.     testHandleProc=NewIconActionProc(TestHandle);
  348.     
  349.     retVal = true;
  350.     ForEachIconDo(theSuite, svAllAvailableData, testHandleProc, &retVal);
  351.     DisposeRoutineDescriptor(testHandleProc);
  352.  
  353.     return(retVal);
  354.     }
  355.  
  356.  
  357.